package com.ms.game.slot.base;

import java.lang.reflect.ParameterizedType;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.LinkedList;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.xpec.c4.game.time.TimeSys;

public abstract class SlotBaseHistoryRecorder<T> implements ISlotBaseHistory
{ 
	@SuppressWarnings("unused")
	private static final Log log = LogFactory.getLog(SlotBaseHistoryRecorder.class);
	
	
	/**
	 * 末開全盤重置
	 */
	public static final int UNOPEN_RESET = 0;
	
	/**
	 * 末開全盤+1
	 */
	public static final int UNOPEN_INCR = 1;
	
	/**
	 * 歷史記錄列表最大個數
	 */
	public static final int HISTORY_MAX_COUNT = 7;
	
	
	/**time format**/
	public static final String HISTORY_TIME_FORMAT = "yyyy/MM/dd 00:00:00";

	/**
	 * 末進全盤轉數
	 */
	private LinkedList<Integer> unopenbouns;
	
	/**
	 * 每日歷史記錄
	 */
	private LinkedList<T> daylist;
	

	public ArrayList<Integer> getUnopenbouns() 
	{
		return new ArrayList<Integer>(unopenbouns);
	}

	public void setUnopenbouns(LinkedList<Integer> unopenbouns) {
		this.unopenbouns = unopenbouns;
	}

	public ArrayList<T> getDaylist() 
	{
		return new ArrayList<T>(daylist);
	}

	public void setDaylist(LinkedList<T> daylist) {
		this.daylist = daylist;
	}
	
	
	T createContents(Class<T> clazz) throws InstantiationException, IllegalAccessException
    {
        return clazz.newInstance();
    }
	
	@SuppressWarnings("unchecked")
	public Class<T> getTypeParameterClass()
    {
       // Type type = (Type) getClass().getGenericSuperclass();
        ParameterizedType paramType = (ParameterizedType) getClass().getGenericSuperclass();
        return (Class<T>) paramType.getActualTypeArguments()[0];
    }
	
	/**
	 * 創建今日資料
	 * @throws IllegalAccessException 
	 * @throws InstantiationException 
	 */
	public T checkAndCreateTodayData() throws InstantiationException, IllegalAccessException
	{
		String nowDate = SlotBaseHistoryRecorder.getDate();
		if(getTodayData(nowDate)!=null)
		{
			return null;
		}
		
		T bb =createContents(getTypeParameterClass());
		((SlotHistoryBase)bb).init(nowDate);
		
		//越新的越前面
		daylist.addFirst(bb);
		if(daylist.size() > HISTORY_MAX_COUNT)
		{
			daylist.removeLast();
		}
		
		return bb;
	}
	
	/**
	 * 更新今日資料
	 * @throws IllegalAccessException 
	 * @throws InstantiationException 
	 */
	public void modifyTodayData(int type , int betmoney , int score) throws InstantiationException, IllegalAccessException
	{
		String date =SlotBaseHistoryRecorder.getDate();
		T t = getTodayData(date);
		
		//找不到就新增
		if(t==null)
		{
			t = checkAndCreateTodayData();
		}
		
		if(type == UNOPEN_RESET)
		{
			int unopen =(this.unopenbouns.size()==0)? 0:this.unopenbouns.getFirst();
			if(unopen == 0)
			{
				if(this.unopenbouns.size()==0)
				{
					this.unopenbouns.addFirst(1);
				}
				else
				{
					this.unopenbouns.set(0, 1);
				}
			}
			
			//新增0
			this.unopenbouns.addFirst(0);
			if(unopenbouns.size() > HISTORY_MAX_COUNT)
			{
				unopenbouns.removeLast();
			}
			
			
			((SlotHistoryBase)t).reset();
		}
		else if(type == UNOPEN_INCR)
		{
			if(this.unopenbouns.size()==0)
			{
				this.unopenbouns.add(0);
			}
			
			int unopen = this.unopenbouns.getFirst();
			unopen++;
			this.unopenbouns.set(0, unopen);
			
			((SlotHistoryBase)t).incr();
		}
		
		
		((SlotHistoryBase)t).update(betmoney, score);
	}
	
	/**
	 * 讀取末進全盤轉數
	 * @return
	 */
	public LinkedList<Integer> getUnopenList()
	{
		return unopenbouns;
	}
	
	/**
	 * 讀取當前末進全盤轉數
	 * @return
	 */
	public int getUnopen()
	{
		if(unopenbouns.size()==0)
		{
			return 0;
		}
		
		return unopenbouns.getFirst();
	}
	
	
	
	/**
	 * 讀取每日進度
	 * @return
	 */
	public LinkedList<T> getDayList()
	{
		return this.daylist;
	}
	
	@SuppressWarnings("unchecked")
	private T getTodayData(String date)
	{
		//有無今日資料
		for(T e:daylist)
		{
			SlotHistoryBase sb = (SlotHistoryBase) e;
			if(sb.date.equals(date))
			{
				return (T)sb;
			}
		}
		
		return null;
	}
	
	/**
	 * 讀取本日時間
	 * @return
	 */
	public static String getDate()
	{
		long nowtime = TimeSys.currentTimeMills();
		SimpleDateFormat ndFormat = new SimpleDateFormat(HISTORY_TIME_FORMAT);
		return  ndFormat.format(nowtime);
	}
}
